package Game;

import java.io.IOException;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;

import server.StateOfGame;
import smash_tris.DataPacket;
import smash_tris.Grid;
import smash_tris.TetrisPiece;
import smash_tris.TypeOfDataPacket;

import Components.TetrisPlayground;
import Connector.Connector;

public class Tetris extends JPanel implements Runnable, KeyListener {
	/** the state of the game */
	TetrisGame game;
	/** the game loop thread */
	Thread gameRunner;
	/** Size of the display area */
	int xs, ys;
	private int xCoord, yCoord;
	ScoreBox box;
	boolean gameOver = false;
	TetrisPlayground motherPanel;
	private Connector connector;
	boolean isStop = false;
	boolean isRunning = false;

	/**
	 * Overrides init() in java.applet.Applet Parses attributes, initializes
	 * variables, calls resize() and getfocus().
	 */

	public Tetris(TetrisPlayground mP, int placeX, int placeY,
			Connector connector) {
		this.connector = connector;
		this.motherPanel = mP;
		init();
	}

	public Tetris(TetrisPlayground mP, Connector connector) {
		this.connector = connector;
		motherPanel = mP;
		init();
	}

	public void init() {

		System.out.println("Class string:" + toString());

		xCoord = 10;

		yCoord = 20;

		gameRunner = null;
		game = new TetrisGame(xCoord, yCoord);
		xs = xCoord * 20 + 10; // Play area
		ys = yCoord * 19 + 16; // Play area
		this.setSize(xs, ys);
		this.setVisible(true);
		this.setLayout(new BorderLayout());

		this.add(game);

	}

	public void start() {
		this.connector.setStart();
		if (gameRunner == null) {
			gameRunner = new Thread(this);
			gameRunner.start();
		}
	}

	public void stop() {
		/*
		 * if (gameRunner.isAlive()) { gameRunner.stop(); }
		 */
		System.out.println("synchronized(game)");
		
		isStop = true;
	/*		if (!isExternal) {
				isStop = true;
			} else {
				gameOver = true;
			}
		*/
		System.out.println("done");
		gameRunner = null;
	}

	/*@SuppressWarnings("deprecation")
	public void stopThread() {
		if (gameRunner != null) {
			gameRunner.stop();
		}
		connector.resetStreams();
	}*/

	public void destroy() {
	}

	public void run() {
		isRunning = true;
		System.out.println("play");
		gameOver = false;
		TetrisGame enemy = this.motherPanel.getEnemy().getGame();
		while (!gameOver) {
			boolean isV = false;

			Grid grid = game.getPlayfield();
			TetrisPiece piece = game.getPiece();
			StateOfGame actState = null;
			Integer px = game.getPx();
			Integer py = game.getPy();

			if (isStop) {
				gameOver = this.connector.stopGame();
			} else {
				StateOfGame state = new StateOfGame(piece, grid, px, py);
				System.out.println("pre try");
				try {
					System.out.println("play...running");
					DataPacket actualData = this.connector.play(state);
					if (actualData.getTypeOfInformation()==TypeOfDataPacket.STATE_OF_GAME){
						actState = (StateOfGame) actualData.getData();
						if (actState != null) {
							enemy.setState(actState.getPiece(), actState.getGrid(),
									actState.getPx(), actState.getPy());
						}

						// enemy.step();
						System.out.println("step...");
						gameOver = game.step();
						if (gameOver) {							
							this.connector.stopGame();
						}
						game.repaint();
					} else if (actualData.getTypeOfInformation() ==
							TypeOfDataPacket.EXIT_FROM_ROOM) {
						
						gameOver = true;
					} else {
						actState = null;
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();

				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block

					e1.printStackTrace();
				} catch (NullPointerException e2) {
					System.out.println("NULL RETURNED");
				}

				
				try {
					Thread.sleep(450);
				} catch (InterruptedException e) {
				}

			}

		}
		this.repaint();
		motherPanel.setEndGame(true);
		System.out.println("EXIT_ROOM_AAAAALLLLL");
		this.connector.resetStreams();
		this.isRunning = false;
	}

	public boolean getIsRunning(){
		return isRunning;
	}
	
	public TetrisGame getGame() {
		return game;
	}

	public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;

		if (gameOver) {
			System.out.println("Przegrałeś :) ");
			Font tmp = getFont();
			g2.setColor(Color.red);
			g2.setFont(new java.awt.Font("TimesRoman", Font.BOLD, 18));
			g2.drawString("Game Over", 10, ys / 2);
			g2.setFont(tmp);
			g2.setColor(Color.BLACK);
		}
	}

	public boolean keyDown(KeyEvent evt) {
		char key = evt.getKeyChar();

		System.out.println(key);
		if (!gameOver) {
			switch (key) {
			case 'a':
			case 'A':
				game.move_left();
				repaint();
				break;
			case 'D':
			case 'd':
				game.move_right();
				repaint();
				break;
			case 'w':
			case 'W':
				game.rotate_ccw();
				repaint();
				break;
			case 's':
			case 'S':
				game.rotate_cw();
				repaint();
				break;
			case ' ':
				game.drop();
				repaint();
				break;
			}
		}

		return true;
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		keyDown(arg0);
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
	}

	public int getSizeX() {
		return this.xs;
	}

	public int getSizeY() {
		return this.ys;
	}

	public int getUserScore() {
		return this.game.getScore();
	}
}
